package net.maku.infra.biz.service.file.impl;



import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import javax.annotation.Resource;
import lombok.SneakyThrows;
import net.maku.commons.biza.util.FileUtils;
import net.maku.infra.biz.controller.file.vo.FilePageReqVO;
import net.maku.infra.biz.controller.file.vo.FileUploadReqVO;
import net.maku.infra.biz.core.file.FileClient;
import net.maku.infra.biz.core.utils.FileTypeUtils;
import net.maku.infra.biz.mapper.file.InfraFileMapper;
import net.maku.infra.biz.pojo.file.InfraFilePojo;
import net.maku.infra.biz.service.file.FileConfigService;
import net.maku.infra.biz.service.file.FileService;
import org.im4java.core.ConvertCmd;
import org.im4java.core.IMOperation;
import org.im4java.core.ImageCommand;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;

/**
 * 文件 Service 实现类
 *
 * @author 哈博智能
 */
@Service
public class FileServiceImpl implements FileService {

    @Resource
    private FileConfigService fileConfigService;

    @Resource
    private InfraFileMapper fileMapper;
    @Value("${iostmp.file.heic}")
    private String tmpHeicPath;
    @Value("${iostmp.file.jpg}")
    private String tmpJpgPath;
    @Override
    public Page<InfraFilePojo> getFilePage(FilePageReqVO pageReqVO) {
        Page<InfraFilePojo> page = Page.of(pageReqVO.getPageNo(), pageReqVO.getPageSize());
        page = fileMapper.selectPage(page,pageReqVO);
        return page;
    }
    
    
    @Override
    @SneakyThrows
    public  String createFile(FileUploadReqVO uploadReqVO) {
    	MultipartFile file = uploadReqVO.getFile();
        String fileName=file.getOriginalFilename();
        InputStream is=file.getInputStream();
        String path = uploadReqVO.getPath();
        if (file.getOriginalFilename().toLowerCase().endsWith("heic")) {//heic转换jpg
			File heic = File.createTempFile(tmpHeicPath, ".heic");
			FileCopyUtils.copy(file.getInputStream(), new FileOutputStream(heic));
			File jpg = File.createTempFile(tmpJpgPath, ".jpg");
			IMOperation op = new IMOperation();
			op.addImage(heic.getPath());
			op.addImage(jpg.getPath());
			ImageCommand convert = new ConvertCmd();
			convert.run(op);
			is=new FileInputStream(jpg);
			fileName=fileName.substring(0, fileName.lastIndexOf("."))+".jpg";
			path=fileName;
			heic.delete();
			jpg.delete();
			
		} 
        return createFile(fileName, path, IoUtil.readBytes(is),uploadReqVO.getSource(),uploadReqVO.isRename());
    }

    @Override
    @SneakyThrows
    public String createFile(String name, String path, byte[] content,String source,boolean isRename) {
        // 计算默认的 path 名
        String type = FileTypeUtils.getMineType(content, name);
        if (StrUtil.isEmpty(path) && isRename) {
            path = FileUtils.generatePath(content, name);
        }else {
        	 path = name;
        }
        // 如果 name 为空，则使用 path 填充
        if (StrUtil.isEmpty(name)) {
            name = path;
        }
        
        //获取文件地址
        path = getFilePath(path, source, type);
          
        // 上传到文件存储器
        FileClient client = fileConfigService.getMasterFileClient();
        Assert.notNull(client, "客户端(master) 不能为空");
        String url = client.upload(content, path, type);

        // 保存到数据库
        InfraFilePojo file = new InfraFilePojo();
        file.setConfigId(client.getId());
        file.setName(name);
        file.setPath(path);
        file.setUrl(url);
        file.setType(type);
        file.setSize(content.length);
        fileMapper.insert(file);
        return url;
    }

	private String getFilePath(String path, String source, String type) {
		if(type.contains("image")) {
        	path=source+"/imgs"+"/"+path;
        }else if(type.contains("txt")) {
        	path=source+"/txts"+"/"+path;
        }else if(type.contains("audio")) {
        	path=source+"/audios"+"/"+path;
        }else if(type.contains("video")) {
        	path=source+"/videos"+"/"+path;
        }else if(type.contains("zips")) {
        	path=source+"/zip"+"/"+path;
        }else if(type.contains("pdf")) {
        	path=source+"/pdfs"+"/"+path;
        }else if(type.contains("excel")) {
        	path=source+"/excels"+"/"+path;
        }else if(type.contains("msword")) {
        	path=source+"/docs"+"/"+path;
        }else {
        	path=source+"/others"+"/"+path;
        }
		return path;
	}

    @Override
    public void deleteFile(Long id) throws Exception {
        // 校验存在
        InfraFilePojo file = validateFileExists(id);

        // 从文件存储器中删除
        FileClient client = fileConfigService.getFileClient(file.getConfigId());
        Assert.notNull(client, "客户端({}) 不能为空", file.getConfigId());
        client.delete(file.getPath());

        // 删除记录
        fileMapper.deleteById(id);
    }

    private InfraFilePojo validateFileExists(Long id) throws Exception {
        InfraFilePojo fileDO = fileMapper.selectById(id);
        if (fileDO == null) {
            throw new Exception("文件不存在");
        }
        return fileDO;
    }

    @Override
    public byte[] getFileContent(Long configId, String path) throws Exception {
        FileClient client = fileConfigService.getFileClient(configId);
        Assert.notNull(client, "客户端({}) 不能为空", configId);
        return client.getContent(path);
    }

}
